\documentclass{report}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{textcomp}
\usepackage{geometry}
\geometry{top=15mm, bottom=15mm, left=1cm, right=1cm}
\usepackage[french]{babel}
\usepackage{pslatex}
\usepackage[colorlinks=true,urlcolor=black]{hyperref}
\usepackage{graphicx}
\usepackage{fancyhdr}
\pagestyle{fancy}
\renewcommand{\footrulewidth}{0.4pt}
\fancyfoot[L]{Uubu.fr}
\fancyfoot[R]{mar. mai 4 01:59:21 CEST 2010}
\lfoot{\Large \textit{Uubu.fr}}
\hypersetup{pdfinfo={
Title={MySQL - Optimisation},
Author={Sylvain Girod},
Creator={Bash script from uubu.fr's format version 1},
Producer={Bash script and PDFLaTeX},
Subject={Optimisation de MySQL},
CreationDate={D:20100504015921},
ModDate={D:20100504015921},
Keywords={mysql;db;databases}
}}
\begin{document}
 
\begin{center}
{\Huge MySQL - Optimisation }
\end{center}
\vspace{1cm}
 
\begin{flushleft}
 
{\large Optimisation de MySQL}
 
\vspace{10mm}
 
\vspace{1cm}{\huge Limitations et inconvénients conceptuels }
 
\
 
\hspace{1mm}  Avec les tables de type \textbf{MyISAM}, MySQL utilise un verrouillage extrêmement rapide (plusieurs lecture / une seule écriture). Le plus gros problème survient quand vous avez un mélange de flux de modifications et des sélections lentes sur la même table. Si c'est un problème sur plusieurs tables, vous pouvez utiliser un autre type de table.
\vspace{5mm} \\
 
 
\vspace{1cm}{\huge Suite de tests MySQL }
 
\
 
\begin{description} \normalsize
\item[\hspace{1mm} crash-me]{est une page web qui test 450 points, utilisé notamment pour la portabilité. Actuellement vous pouvez vous faire une idée des tests en regardant le code et les résultats dans le répertoire \textbf{sql-bench}.}
\item[\hspace{1mm} ]{Les scripts de test ont été écrit en perl et utilisent le module \textbf{perl DBI}. Vous aurez aussi avoir besoin des pilotes spécifiques DBD de chaque serveurs que vous testez.}
\end{description}
 
\hspace{1mm} La suite de tests est située dans le dossier sql-bench. Pour exécuter la suite de tests, lancer run-all-tests \\
\hspace{1mm} \textbf{cd sql-bench} \\
\hspace{1mm} \textbf{perl run-all-tests --server=server\_name} \\
 
\begin{description} \normalsize
\item[\hspace{1mm} Super Smack]{est un utilitaire de test, qui peut mettre le serveur à genou, utile pour tester les fortes charges du serveur avant sa mise en production.}
\end{description}
 
\vspace{1cm}{\huge Optimisation des commandes SELECT et autres requêtes }
 
\
 
\begin{description} \normalsize
\item[\hspace{1mm} -]{Premièrement, ce qui affecte toutes les requêtes: plus votre système de droits est compliqué, plus vous aurez des baisses de performances.}
\item[\hspace{1mm} -]{Si vous n'avez aucun \textbf{GRANT}, MySQL optimisera les vérifications de droit, pour les système volumineux, il est bénéfique d'éviter \textbf{GRANT}.}
\item[\hspace{1mm} -]{Si vous n'avez pas de droits de niveau tables ou colonne, le serveur n'a pas à vérifier le contenu des tables \textbf{tables\_priv} et \textbf{columns\_priv}.}
\item[\hspace{1mm} -]{Similairement, si vous n'avez pas de limites de ressources, le serveur n'a pas de comptes de ressources à faire.}
\item[\hspace{1mm} -]{si le problème est spécifique à une expression MySQL ou une fonction, vous pouvez utiliser la fonction \textbf{BENCHMARK()} pour effectuer un test de performances. la syntaxe est \textbf{BENCHMARK(100000,1+1G);}}
\end{description}
 
\vspace{1cm}{\huge Syntaxe Explain (Obtenir des informations sur SELECT) }
 
\
 
\begin{description} \normalsize
\item[\hspace{1mm} EXPLAIN tbl\_name]{ou}
\item[\hspace{1mm} EXPLAIN SELECT tbl\_name]{}
\item[\hspace{1mm} EXPLAIN tbl\_name]{est un synonyme de \textbf{DESCRIBE tbl\_name} ou \textbf{SHOW COLUMNS FROM tbl\_name}}
\end{description}
 
\hspace{1mm}  Lorsque vous faite précéder \textbf{SELECT} avec \textbf{EXPLAIN}, MySQL vous explique comment il va traiter la commande \textbf{SELECT}, choisir les tables et index pour les jointures. Avec \textbf{EXPLAIN}, vous pouvez identifier les index à ajouter pour accélérer les commandes \textbf{SELECT}.Vous devriez souvent utiliser la commande \textbf{ANALYSE TABLE} pour mettre à jour les statistiques de cardinalité de vos tables, qui affectent les choix de l'optimiseur.
\vspace{5mm} \\
 
 
\hspace{1mm}  En général, lorsque vous voulez rendre un \textbf{SELECT ... WHERE} plus rapide, la première chose à faire est de voir si vous pouvez ajouter des index. Toutes les références entre les tables doivent normalement être faites avec des index. Vous pouvez utiliser la commande \textbf{EXPLAIN} pour déterminer les index utilisés pour le \textbf{SELECT}.
\vspace{5mm} \\
\hspace{1mm}  Pour aider MySQL à mieux optimiser les requêtes, exécutez \textbf{myisamchk --analyze} sur une table après l'avoir remplie avec quelques données consistantes. Cela met à jour une valeur pour chaque partie de l'index qui indique le nombre moyen de lignes qui ont la même valeur. Vous pouvez vérifier le retour de l'exécution d'analyze en faisant \textbf{SHOW INDEX FROM nom\_de\_table} et examiner la colonne \textbf{Cardinality}.
\vspace{5mm} \\
 
 
\hspace{1mm}  Pour trier un index et des données par rapport à un index, utilisez \textbf{myisamchk --sort-index --sort-records=1} (si vous voulez trier selon le premier index). Notez, toutefois, que ce tri n'est pas le plus optimal et prendra beaucoup de temps pour une grosse table.\textbf{EXPLAIN} affiche la valeur \textbf{ALL} dans la colonne type lorsque MySQL utilise n scans de table pour résoudre une requête. Cela arrive par exemple lorsque la table est si petite qu'il est plus rapide d'analyser la table que d'utiliser les index. C'est un cas courant pour les tables de moins de 10 lignes, et de taille de ligne faible.
\vspace{5mm} \\
 
 
\hspace{1mm} Pour éviter les scans de grosses tables \\
\hspace{1mm} \textbf{ANAYZE TABLE} \\
\hspace{1mm} Pour forcer l'utilisation d'un index \\
\hspace{1mm} \textbf{FORCE INDEX.} \\
 
\vspace{1cm}{\huge Conception }
 
\
 
\hspace{1mm}  MySQL conserve les données et les index dans deux fichiers séparés. De nombreux (et en fait presque toutes) les autres bases mélangent les données et les index dans le même fichier.
\vspace{5mm} \\
 
 
\begin{description} \normalsize
\item[\hspace{1mm} -]{Rendre les tables aussi compact que possible}
\item[\hspace{1mm} -]{réduire la taille des données optimise les performances, l'indexation de colonnes de petites taille prend aussi moins de ressources.}
\item[\hspace{1mm} -]{utiliser les types les plus efficaces et les plus petits possible}
\item[\hspace{1mm} -]{utiliser les types d'entiers les plus petits possibles, par exemple \textbf{MEDIUMINT} est préférable a \textbf{INT}}
\item[\hspace{1mm} -]{Déclarez des colonnes \textbf{NOT NULL} si possibles colonnes de taille variable prennent moins de place sur le disque}
\item[\hspace{1mm} -]{la clé primaire doit être aussi courte que possible, cela rend l'identification des lignes plus efficace.}
\item[\hspace{1mm} -]{Ne créer que des index dont vous avez besoin, les index sont bons pour accélérer les lectures, mais sont plus lents pour les écriture des données}
\item[\hspace{1mm} -]{s'il est probable qu'une colonne a un préfixe unique avec les premiers caractères, il est mieux de n'indexer que ce préfixe.}
\item[\hspace{1mm} -]{il peut être parfois intéressant de séparer en 2 une table qui est scannée très souvent.}
\end{description}
 
\begin{description} \normalsize
\item[\hspace{1mm} -]{tous les types de colonnes de MySQL peuvent être indexés.}
\item[\hspace{1mm} -]{vous pouvez avec tous les gestionnaire de tables avoir au moins 16 clés et une taille d'index d'au moins 256 octets.}
\item[\hspace{1mm} -]{pour les colonnes \textbf{CHAR} et \textbf{VARCHAR}, il est possible d'indexer un préfixe de la colonne.}
\item[\hspace{1mm} -]{les moteurs de table \textbf{MyISAM} et \textbf{InnoDB} supportent aussi l'indexation des colonnes \textbf{BLOB} et \textbf{TEXT}. Lors de l'indexation, vous devez spécifier une taille pour l'index:}
\item[\hspace{1mm} CREATE TABLE test (blob\_col BLOB, INDEX(blob\_col(10)));]{}
\item[\hspace{1mm} -]{MySQL peut créer des index sur plusieurs colonnes. Un index peut comprendre jusqu'à 15 colonnes (sur les colonnes de type \textbf{CHAR} et \textbf{VARCHAR}, vous pouvez utiliser uniquement le début de la colonne pour l'indexation).}
\item[\hspace{1mm} -]{Un index sur plusieurs colonnes peut être compris comme un tableau trié contenant des valeurs créées par concaténation des valeurs des colonnes indexées.}
\end{description}
 
\hspace{1mm} \textbf{mysql> CREATE TABLE test (} \\
\hspace{1mm} \textbf{-> id INT NOT NULL,} \\
\hspace{1mm} \textbf{-> nom CHAR(30) NOT NULL,} \\
\hspace{1mm} \textbf{-> prenom CHAR(30) NOT NULL,} \\
\hspace{1mm} \textbf{-> PRIMARY KEY (id),} \\
\hspace{1mm} \textbf{-> INDEX nom\_index (nom,prenom)) ;} \\
\hspace{1mm} l'index nom\_index sera utilisé pour les requêtes suivantes: \\
\hspace{1mm} \textbf{mysql> SELECT * FROM test WHERE nom="Widenius" ;} \\
\hspace{1mm} \textbf{mysql> SELECT * FROM test WHERE nom="Widenius"} \\
\hspace{1mm} \textbf{-> AND prenom="Michael" ;} \\
\hspace{1mm} \textbf{mysql> SELECT * FROM test WHERE nom="Widenius"} \\
\hspace{1mm} \textbf{-> AND (prenom="Michael" OR prenom="Monty") ;} \\
\hspace{1mm} \textbf{mysql> SELECT * FROM test WHERE nom="Widenius"} \\
\hspace{1mm} \textbf{-> AND prenom >="M" AND prenom < "N" ;} \\
\hspace{1mm} mais nom\_index ne sera pas utilisé pour: \\
\hspace{1mm} \textbf{mysql> SELECT * FROM test WHERE prenom="Michael" ;} \\
\hspace{1mm} \textbf{mysql> SELECT * FROM test WHERE nom="Widenius"} \\
\hspace{1mm} \textbf{-> OR prenom="Michael" ;} \\
\hspace{1mm} Tous les index de MySQL (PRIMARY, UNIQUE et INDEX) sont stockés sous la forme de B-tree. \\
 
\vspace{1cm}{\huge Cache des tables MyISAM }
 
\
 
\hspace{1mm}  MyISAM utilise un cache qui garde en mémoire les blocs de tables les plus souvent utilisés. Pour les blocs d'index, un buffer de clés est utilisé. Pour les blocs de données, MySQL n'utilise pas de cache, mais exploite le cache natif du système de fichiers.
\vspace{5mm} \\
\hspace{1mm}  Les accès aux caches de clés sont à accès simultanés entre les threads. Vous pouvez configurer plusieurs caches de clés, et assigner différents index de tables spécifiquement.
\vspace{5mm} \\
\hspace{1mm}  Pour contrôler la taille du cache: \textbf{key\_buffer\_size}. À 0, le cache est désactivé. Le cache de clé est désactivé si la taille du buffer est top petite.
\vspace{5mm} \\
 
 
\begin{description} \normalsize
\item[\hspace{1mm} Sans cache de clé,]{les fichiers d'index sont lus avec le cache du système de fichier.}
\item[\hspace{1mm} Accès au cache:]{un buffer non modifié est en accès simultanné, s'il est modifié, les threads sont en attente.}
\item[\hspace{1mm} Cache de clé multiple:]{pour assigner un index à un cache spécifique:}
\item[\hspace{1mm} CACHE INDEX]{}
\end{description}
 
\hspace{1mm} Les 2 commandes suivantes assignent les index des tables t1, t2 et t3 au cache de clé appelé hit\_cache \\
\hspace{1mm} \textbf{mysql> CACHE INDEX t1, t2, t3 IN hot\_cache ;} \\
 
{\ttfamily
+---------+--------------------+----------+----------+\\ |--Table--|---------Op---------|-Msg\_type-|-Msg\_text-|\\ +---------+--------------------+----------+----------+\\ |-test.t1-|-assign\_to\_keycache-|--status--|----OK----|\\ |-test.t2-|-assign\_to\_keycache-|--status--|----OK----|\\ |-test.t3-|-assign\_to\_keycache-|--status--|----OK----|\\ +---------+--------------------+----------+----------+\\
}
\vspace{8mm}
 
\hspace{1mm} le cache de clé peut être crée en spécifiant sa taille avec le paramètre \\
\hspace{1mm} \textbf{mysql> SET GLOBAL keycache1.key\_buffer\_size=128*1024;} \\
\hspace{1mm} pour détruire le cahce, lui donner une taille de 0 \\
\hspace{1mm} \textbf{mysql> SET GLOBAL keycache1.key\_buffer\_size=0;} \\
 
\begin{description} \normalsize
\item[\hspace{1mm} Pour un serveur en charge, nous recommandons la stratégie suivante pour le cache de clés:]{}
\item[\hspace{1mm} -]{Un cache de clés principal qui représente 20\% de l'espace alloué pour tous les caches de clés. Il sera utilisé par les tables qui sont le plus sollicitées, mais qui ne sont pas modifiées.}
\item[\hspace{1mm} -]{Un cache de clé minoritaire qui représente 20\%, Il sera utilisé pour les tables intermédiaires, qui sont intensivement modifiés, comme des tables temporaires par exemple.}
\item[\hspace{1mm} -]{Un cache de clés secondaire qui représente 60\% qui sera le cache par défaut, utilisé pour toutes les autres tables.}
\end{description}
 
\vspace{1cm}{\huge Stratégie d'insertion au milieu }
 
\
 
\hspace{1mm}  Par défaut le système de gestion de cache utilise la stratégie \textbf{LRU} (le moins utilisé est remplacé en premier). On peut choisir la stratégie de l'insertion par le milieu.
\vspace{5mm} \\
\hspace{1mm}  Lors de l'utilisation de la stratégie d'insertion au milieu, la chaîne \textbf{LRU} est divisée en deux parties: une sous-chaîne principale, et une sous-chaîne secondaire. Le point de division entre les deux parties n'est pas fixé, mais le système s'assure que la partie principale n'est pas "trop petite", et qu'elle contient au moins \textbf{key\_cache\_division\_limit \%} de bloc de cache de clés. \textbf{key\_cache\_division\_limit} est un composant d'une variable structurée de cache de clé, et sa valeur peut être modifiée indépendamment pour chaque cache.
\vspace{5mm} \\
 
 
\hspace{1mm}  Lorsqu'un bloc d'index est lu dans une table, depuis le cache de clé, il est placé à la fin de la sous-chaîne secondaire. Après un certain nombre d'accès, il est promu dans la sous-chaîne principale. Un bloc de la chaîne principale est placé à la fin de la chaîne. Le bloc circule alors dans la la sous-chaîne. Si le bloc reste à la fin de la sous-chaîne suffisamment longtemps, il est rétrogradé dans la chaîne secondaire. Ce temps est déterminé par la valeur du composant \textbf{key\_cache\_age\_threshold}.
\vspace{5mm} \\
\hspace{1mm}  La stratégie de l'insertion au milieu vous permet de garder les blocs les plus utilisés dans le cache. Si vous préférez utiliser la stratégie \textbf{LRU} classique, laissez la valeur de \textbf{key\_cache\_division\_limit} à 100.
\vspace{5mm} \\
 
 
\hspace{1mm}  La stratégie d'insertion au milieu aide à améliorer les performances lorsque l'exécution d'une requête qui requiert un scan d'index place dans le cache toutes les valeurs de l'index. Pour éviter cela, vous devez utiliser la stratégie d'insertion au milieu, avec une valeur très inférieure à 100 pour \textbf{key\_cache\_division\_limit}. Les blocs les plus utilisés seront conservés dans le cache durant un tel scan.
\vspace{5mm} \\
 
 
\vspace{1cm}{\huge Préchargement des index }
 
\
 
\hspace{1mm}  S'il y a suffisamment de blocs dans le cache de clé pour contenir tout un index, ou au moins les blocs correspondant aux blocs non-terminaux, alors cela vaut la peine de pré-charger l'index avant de commencer à l'utiliser. Le pré-chargement vous permet de mettre les blocs d'index dans un buffer de cache le plus efficacement : il lit les blocs séquentiellement sur le disque.
\vspace{5mm} \\
 
 
\hspace{1mm} Pour pré-charger un index dans un cache \\
\hspace{1mm} \textbf{LOAD INDEX INTO CACHE} \\
\hspace{1mm} Par exemple, la commande suivante précharge les index des tables t1 et t2 \\
\hspace{1mm} \textbf{mysql> LOAD INDEX INTO CACHE t1, t2 IGNORE LEAVES;} \\
\hspace{1mm} L'option \\
\hspace{1mm} \textbf{IGNORE LEAVES} \\
\hspace{1mm} fait que les blocs non-terminaux seuls seront lus dans l'index. Par conséquent, la commande ci-dessus va charger tous les blocs de l'index de t1, mais uniquement les blocs non-terminaux de t2 \\
\hspace{1mm} Un cache de clé peut être restructuré à tout moment, en modifiant les valeurs de ses paramètres \\
\hspace{1mm} \textbf{mysql> SET GLOBAL cold\_cache.key\_buffer\_size=4*1024*1024;} \\
\hspace{1mm} Si vous assignez une nouvelle valeurs aux variables \textbf{key\_buffer\_size} ou \textbf{key\_cache\_block\_size}, le serveur va détruire l'ancienne structure du cache, et en recréer un \\
 
\vspace{1cm}{\huge Quand MySQL ouvre et ferme les tables }
 
\
 
\begin{description} \normalsize
\item[\hspace{1mm} table\_cache, max\_connections et max\_tmp\_tables]{affectent le nombre maximum de tables que le serveur garde ouvertes.}
\item[\hspace{1mm} table\_cache]{est lié au \textbf{max\_connections}.}
\end{description}
 
\hspace{1mm}  Par exemple, pour 200 connexions simultanées, vous devriez avoir un cache de table d'environ \textbf{200*n}, où n est le nombre maximum de table dans une jointure. Vous devez aussi réserver des pointeurs de fichiers supplémentaires pour les tables temporaires et les fichiers. Assurez vous que votre système d'exploitation peut gérer le nombre de pointeurs de fichiers demandé par l'option \textbf{table\_cache}. Si \textbf{table\_cache} est trop grand, MySQL peut être à court de pointeurs, et refuser des connexions, échouer à l'exécution de requêtes, ou être très instable. Vous devez aussi prendre en compte que les tables MyISAM peuvent avoir besoin de deux pointeurs de fichiers pour chaque table différente. Vous pouvez augmenter le nombre de pointeurs de fichiers disponibles pour MySQL avec l'option de démarrage \textbf{-open-files-limit=\#}.
\vspace{5mm} \\
 
 
\hspace{1mm}  Le cache de tables ouvertes reste au niveau de \textbf{table\_cache} entrées (par défaut, 64 ; cela peut être modifié avec l'option \textbf{-O table\_cache=\#} de mysqld). Notez que MySQL peut ouvrir temporairement plus de tables, pour être capable d'exécuter des requêtes.
\vspace{5mm} \\
\hspace{1mm}  Une table qui n'est pas utilisée est refermée, et supprimée du cache de table, dans les circonstances suivantes:
\vspace{5mm} \\
 
 
\begin{description} \normalsize
\item[\hspace{6mm} -]{Lorsque le cache est plein, et qu'un thread essaie d'ouvrir une table qui n'est pas dans le cache.}
\item[\hspace{6mm} -]{Lorsque le cache contient plus de table\_cache lignes, et qu'aucun thread n'utilise cette table.}
\item[\hspace{6mm} -]{Lorsque quelqu'un utilise la commande mysqladmin refresh ou mysqladmin flush-tables.}
\item[\hspace{6mm} -]{Lorsque quelqu'un exécute la commande FLUSH TABLES.}
\end{description}
 
\hspace{1mm}  Si vous ouvrez une table avec \textbf{HANDLER table\_name OPEN}, un objet de table dédié sera alloué pour le thread. Cet objet de table n'est pas partagé avec les autres threads, et il ne sera pas fermé avant que le thread n'appelle \textbf{HANDLER table\_name CLOSE}, ou que le thread ne meurt
\vspace{5mm} \\
 
 
\vspace{1cm}{\huge Optimiser le serveur mysql }
 
\
 
\hspace{1mm} Si vous avez bcp de RAM et que vous voulez des performances maximales, vous pouvez essayer \\
\hspace{1mm} \textbf{shell> safe\_mysqld -O key\_buffer=64M -O table\_cache=256 -O sort\_buffer=4M -O read\_buffer\_size=1M \&} \\
\hspace{1mm} Si vous n'avez que 128 Mo et seulement quelques tables, mais que vous demandez beaucoup de classements, vous pouvez essayer cela \\
\hspace{1mm} \textbf{shell> safe\_mysqld -O key\_buffer=16M -O sort\_buffer=1M} \\
\hspace{1mm} Si vous avez peu de mémoire et beaucoup de connections, essayez cela \\
\hspace{1mm} \textbf{shell> safe\_mysqld -O key\_buffer=512k -O sort\_buffer=100k -O read\_buffer\_size=100k \&} \\
\hspace{1mm} Ou encore \\
\hspace{1mm} \textbf{shell> safe\_mysqld -O key\_buffer=512k -O sort\_buffer=16k -O table\_cache=32 -O read\_buffer\_size=8k -O net\_buffer\_length=1K \&} \\
 
\hspace{1mm}  Si vous utilisez \textbf{GROUP BY} ou \textbf{ORDER BY} sur des fichiers de taille supérieure à la mémoire disponible, vous devriez augmenter la valeur de \textbf{record\_rnd\_buffer} pour accélérer la lecture des lignes après que le classement ait été fait
\vspace{5mm} \\
\hspace{1mm}  A l'installation de MySQL, un répertoire \textbf{support-files} est créé, et contient plusieurs exemples de fichiers \textbf{my.cnf}: \textbf{my-huge.cnf}, \textbf{my-large.cnf}, \textbf{my-medium.cnf} et \textbf{my-small.cnf}. Vous pouvez les utiliser comme base pour optimiser votre système.
\vspace{5mm} \\
\hspace{1mm}  Si vous avez vraiment beaucoup de connections, des problèmes peuvent apparaître avec le fichier d'échange si mysqld n'a pas été configuré pour utiliser peu de mémoire pour chaque connexion. mysqld fonctionne mieux si vous avez suffisamment de mémoire pour toutes les connections.
\vspace{5mm} \\
 
 
\hspace{1mm} Pour voir les effets d'un changement de paramètre, essayez \\
\hspace{1mm} \textbf{shell> mysqld -O key\_buffer=32m --help} \\
 
\hspace{1mm}  MySQL 5.0.1 propose une nouvelle méthode plus souple pour l'optimisation, qui permet à l'utilisateur de contrôler l'exhaustivité de la recherche de l'optimisateur dans sa quête pour la méthode la plus efficace pour traiter une requête. L'idée générale est que plus le nombre de méthodes étudiées est petit, moins l'optimisateur prendra de temps à compiler la requête.
\vspace{5mm} \\
\hspace{1mm}  La variable \textbf{optimizer\_prune\_level} indique à l'optimisateur d'omettre des méthodes basées sur l'estimation du nombre de lignes utilisées dans les tables. Notre expérience montre que ce type de "prévision" échoue rarement, tout en réduisant considérablement le temps de compilation des requêtes. C'est pour cela que cette variable est active par défaut.
\vspace{5mm} \\
 
 
\hspace{1mm}  La variable \textbf{optimizer\_search\_depth} indique la "profondeur" d'analyse de l'optimisateur. Les valeurs les plus faibles de \textbf{optimizer\_search\_depth} peuvent conduire à de grandes différences dans le temps de compilation. Par exemple, une requête avec 12-13 ou plus peut facilement prendre des heures ou des jours à compiler si \textbf{optimizer\_search\_depth} a une valeur proche du nombre de tables à traiter. Mais, si \textbf{optimizer\_search\_depth} vaut 3 ou 4, le compilateur peut traiter cette requête en une minute environ. Si vous n'êtes pas sûrs de la valeur raisonnable de \textbf{optimizer\_search\_depth}, donnez lui la valeur de 0 pour que l'optimisateur puisse déterminer la valeur automatiquement.
\vspace{5mm} \\
 
 
\vspace{1cm}{\huge Influence de la compilation et des liaisons sur la vitesse de MySQL }
 
\
 
\hspace{1mm}  Les exécutables les plus rapides sont obtenus en liant avec \textbf{-static}. le code le plus rapide sera obtenu en compilant avec \textbf{pgcc} et \textbf{-O3}.
\vspace{5mm} \\
\hspace{1mm}  Il est aussi possible d'utiliser \textbf{CXX=gcc} à la configuration de MySQL pour éviter l'inclusion de la bibliothèque libstdc++ (qui n'est pas nécessaire).
\vspace{5mm} \\
\hspace{1mm}  A la compilation de MySQL, vous devriez uniquement utiliser le support des caractères que vous allez utiliser. (Option \textbf{--with-charset=xxx}.)
\vspace{5mm} \\
 
 
\vspace{1cm}{\huge Liste des mesures que nous avons effectués }
 
\
 
\begin{description} \normalsize
\item[\hspace{1mm} -]{L'utilisation de \textbf{pgcc} et la compilation complète avec l'option \textbf{-O6} donne un serveur mysqld 1\% plus rapide qu'avec \textbf{gcc 2.95.2}.}
\item[\hspace{1mm} -]{Si vous utilisez la liaison dynamique (sans \textbf{-static}), le résultat est 13\% plus lent sur Linux.}
\item[\hspace{1mm} -]{Sachez que vous pouvez néanmoins utiliser la liaison dynamique pour les bibliothèques de MySQL. Seul le serveur a des performances critiques.}
\item[\hspace{1mm} -]{Si vous allégez votre binaire mysqld avec l'option \textbf{strip libexec/mysqld}, vous obtenez un binaire jusqu'à 4\% plus rapide.}
\item[\hspace{1mm} -]{Si vous utilisez TCP/IP plutôt que les sockets Unix, le résultat est 7.5\% plus lent sur le même ordinateur. (Si vous vous connectez sur localhost, MySQL utilisera les sockets par défaut.)}
\item[\hspace{1mm} -]{Si vous vous connectez en TCP/IP depuis un autre ordinateur avec un lien Ethernet 100 Mo/s, le résultat sera 8 à 11\% plus lent.}
\item[\hspace{1mm} -]{L'utilisation de connections sécurisées ( toutes les données chiffrées par le support interne de SSL) pour nos tests comparatifs a provoqué une perte de vitesse de 55\%.}
\item[\hspace{1mm} -]{Si vous compilez avec \textbf{--with-debug=full}, vous perdrez 20\% de performances sur la plupart des requêtes, mais la perte peut être plus importante sur certaines requêtes}
\item[\hspace{1mm} -]{La compilation sur Linux-x86 avec gcc sans les pointeurs \textbf{-fomit-frame-pointer} ou \textbf{-fomit-frame-pointer -ffixed-ebp} rend mysqld 1 à 4\% plus rapide.}
\end{description}
 
\vspace{1cm}{\huge Gestion de la mémoire du serveur }
 
\
 
\begin{description} \normalsize
\item[\hspace{1mm} -]{Le buffer de clés (variable key\_buffer\_size) est partagé par tous les threads. Les autres buffers sont alloués par le serveur suivant les besoins.}
\item[\hspace{1mm} -]{Chaque connexion utilise un espace spécifique au thread:}
\end{description}
 
\begin{description} \normalsize
\item[\hspace{6mm} -]{une pile (par défaut, 64 ko, variable thread\_stack),}
\item[\hspace{6mm} -]{un buffer de connexion (variable net\_buffer\_length),}
\item[\hspace{6mm} -]{un buffer de résultat (variable net\_buffer\_length).}
\item[\hspace{6mm} -]{Le buffer de connexion et celui de résultat sont dynamiquement élargit jusqu'à max\_allowed\_packet suivant les besoins. Lorsque la requête s'exécute, une copie de la chaîne de requête est aussi allouée.}
\end{description}
 
\begin{description} \normalsize
\item[\hspace{1mm} -]{Tous les threads partagent la même mémoire de base.}
\item[\hspace{1mm} -]{Chaque requête qui effectue une analyse séquentielle d'une table, alloue un buffer de lecture (variable record\_buffer).}
\item[\hspace{1mm} -]{Lors de la lecture de lignes en ordre 'aléatoire' (par exemple, après un tri), un buffer de lecture aléatoire est allouée pour éviter les accès disques (variable record\_rnd\_buffer).}
\item[\hspace{1mm} -]{Toutes les jointures sont faîtes en une seule passe, et la plupart des jointure sont faîtes sans utiliser de table temporaire. La plupart des table temporaires sont faîtes en mémoire (table HEAP). Les tables temporaires avec beaucoup de données (calculées comme la somme des tailles de toutes les colonnes) ou qui contiennent des colonnes de type BLOB sont sauvées sur le disque.}
\item[\hspace{1mm} -]{La plupart des requêtes qui sont triées allouent un buffer de tri, et entre 0 et 2 fichiers temporaires}
\item[\hspace{1mm} -]{Toute l'analyse et les calculs sont faits en mémoire locale. Aucune mémoire supplémentaire n'est nécessaire pour les petits calculs, et les allocations et libérations de mémoire sont évités. La mémoire n'est allouée que pour les chaînes très grandes}
\item[\hspace{1mm} -]{Chaque fichier d'index est ouvert une fois, et le fichier de données est ouvert pour chaque thread concurrent. Pour chaque thread concurrent, une structure de table, une structure de colonne pour chaque colonne et un buffer de taille 3 * n est alloué (où n est la taille maximale de ligne, en dehors des colonnes de type BLOB). Une colonne de type BLOB utilise 5 à 8 octets de plus que la taille des données du BLOB. Les gestionnaires de table ISAM/MyISAM utilisent un buffer d'une ligne de plus pour leur utilisation interne}
\item[\hspace{1mm} -]{Pour chaque table qui a une colonne BLOB, un buffer est dynamiquement agrandi pour lire les valeurs BLOB. Si vous analysez toute une table, un buffer aussi grand que la plus grande valeur de la colonne BLOB sera alloué.}
\item[\hspace{1mm} -]{Les gestionnaires de tables pour les tables en cours d'utilisation sont sauvées dans un cache, et géré comme une pile FIFO. Normalement, ce cache contient 64 lignes. Si une table doit être utilisée par deux threads concurrents simultanément, le cache contiendra deux entrées pour la table.}
\end{description}
 
\vspace{1cm}{\huge MySQL et DNS }
 
\
 
\begin{description} \normalsize
\item[\hspace{1mm} -]{Si votre service DNS est très lent et que vous avez beaucoup d'hôtes, vous pouvez améliorer les performances soit en désactivant le DNS avec \textbf{--skip-name-resolve}, soit en augmentant la taille de \textbf{HOST\_CACHE\_SIZE} (par défaut : 128) et en recompilant mysqld}
\item[\hspace{1mm} -]{Il est possible de désactiver le cache de noms d'hôte avec \textbf{--skip-host-cache}.}
\item[\hspace{1mm} -]{Il est possible de vider le cache des noms d'hôtes avec \textbf{FLUSH HOSTS} ou avec \textbf{mysqladmin flush-hosts}.}
\item[\hspace{1mm} -]{Si vous ne voulez pas autoriser les connections par TCP/IP, vous pouvez utiliser l'option \textbf{--skip-networking} au démarrage de mysqld.}
\end{description}
 
\vspace{1cm}{\huge Problème avec les disques }
 
\
 
\hspace{1mm}  \textbf{Utiliser des liens symboliques}
\vspace{5mm} \\
\hspace{1mm}  Cela signifie que vous allez faire un lien symbolique sur le fichier d'index et/ou le fichier de données sur un autre disque. Cela améliore les lectures et écriture.
\vspace{5mm} \\
\hspace{1mm}  Sous Linux, vous pouvez améliorer les performances (jusqu'à 100\% en charge n'est pas difficile) en utilisant \textbf{hdparm} pour configurer votre interface disque.
\vspace{5mm} \\
 
 
\hspace{1mm} La commande suivante doit être une série de bonnes options de hdparm pour MySQL (et probablement d'autres applications) \\
\hspace{1mm} \textbf{hdparm -m 16 -d 1} \\
\hspace{1mm} Si vous n'avez pas besoin de savoir quand un fichier a été accédé la dernière fois (ce qui n'est pas utile avec un serveur de base de données), vous pouvez monter votre système de fichier avec l'option \\
\hspace{1mm} \textbf{-o noatime} \\
\hspace{1mm} vous pouvez monter des disques avec l'option \\
\hspace{1mm} \textbf{-o async} \\
\hspace{1mm} pour que le système de fichiers soit modifié de manière asynchrone. \\
\end{flushleft}
\end{document}
